﻿using System.Collections.Generic;
using Duality;
using Duality.Components;
using Duality.Resources;
using OpenTK;

namespace ClientApp
{
	public enum DamageType
	{
		Rock,
		Paper,
		Scissor
	}
	public enum ArmorType
	{
		Normal,

		Rock,
		Paper,
		Scissor,

		Headquarter
	}

	public static class ExtMethodsArmorType
	{
		private static float[][] armorTable = new[] { 
			new[] { 1.0f, 1.0f, 1.0f },		// Normal Armor

			new[] { 1.0f, 2.0f, 0.75f },	// Rock Armor
			new[] { 0.75f, 1.0f, 2.0f },	// Paper Armor
			new[] { 2.0f, 0.75f, 1.0f }, 	// Scissor Armor

			new[] { 0.1f, 0.025f, 0.025f }	// Headquarter Armor
		};

		public static float GetDamageFactor(this ArmorType armor, DamageType damage)
		{
			return armorTable[(int)armor][(int)damage];
		}
	}

    public abstract class Creature : Component, ICmpInitializable, ICmpUpdatable
    {
		private	static List<Creature> instances = new List<Creature>();
		public static IEnumerable<Creature> Instances
		{
			get { return instances; }
		}

		private PlayerIdentity playerId = PlayerIdentity.Unknown;
		private	ArmorType armorType = ArmorType.Normal;
		private float hp = 1.0f;

		public PlayerIdentity PlayerId
		{
			get { return this.playerId; }
			set { this.playerId = value; }
		}
		public ArmorType ArmorType
		{
			get { return this.armorType; }
			set { this.armorType = value; }
		}
		public float Hitpoints
		{
			get { return this.hp; }
			set { this.hp = value; }
		}
        public abstract float PhysicalBoundRad { get; }

		public virtual void OnInit(Component.InitContext context) 
		{
			if (context == InitContext.Activate) instances.Add(this);
		}
		public virtual void OnShutdown(Component.ShutdownContext context)
		{
			if (context == ShutdownContext.Deactivate) instances.Remove(this);
		}

		public virtual void OnUpdate()
		{
			if (this.hp <= 0.0f) this.Die();
		}

		public void DoDamage(float damage, DamageType type)
		{
			this.hp = MathF.Max(0.0f, this.hp - damage * this.armorType.GetDamageFactor(type));
		}
		public virtual void Die()
		{
			// clean up
			this.hp = 0.0f;
			this.GameObj.DisposeLater();
		}
	}
}
